home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / programm.ing / falcon / nt_dsp1.lzh / NT_DSP1.MSA / AUDIO / RVB1.ASM < prev    next >
Encoding:
Assembly Source File  |  1990-01-17  |  17.1 KB  |  431 lines

  1. ;  filename:RVB1.ASM
  2. ;
  3. ;    This version of the reverberation program was written with the
  4. ;    objective of maintaining clarity, so one may easily vary different
  5. ;    parameters to hear their affect on the sound.  To this end, it was 
  6. ;    necessary to limit the use of the parallel moves.  Additionally,
  7. ;    there may be superflous MOVES and CLR instructions, to allow
  8. ;    one to disable certain functional blocks while still operating
  9. ;    other algorithm parts.   Final code implementation should
  10. ;    eventually use the parallel move feature to reduce code size
  11. ;    and execution time.
  12. ;
  13. ;                Motorola DSP Group
  14. ;                Austin, Tx
  15. ;
  16. ;**************************************************************************
  17. ; This program was originally available on the Motorola DSP bulletin board
  18. ; and is provided under a DISCLAIMER OF WARRANTY available from Motorola
  19. ; DSP Operation, 6501 William Cannon Dr. W Austin, Texas  78735-8598.
  20. ;**************************************************************************
  21. ;--------------------------------------------------------------------------
  22. ;    This reverberation program is a variation of the reverberation
  23. ;    system and structures as described by James Moorer's article entitled
  24. ;     'About this Reverberation Business', Computer Music Journal,
  25. ;     3(2):13-28, 1979
  26. ;
  27. ;    Structure is:
  28. ;                                                       .----------.
  29. ;                            .------------.   .-----.   | All Pass |
  30. ;                         +->| Comb Filter|-->| SUM |-->| Reverb   |
  31. ;   Note: All Comb        |  |   #1       |   '-----'   |          |
  32. ;         Filters         |  '------------'   ^  ^  ^   '----------'
  33. ;         Have a 1st      |  .------------.   |  |  |        |
  34. ;         Order IIR       |->| Comb Filter|---+  |  |    .---V---.
  35. ;         LPF in their    |  |   #2       |      |  |    | align |
  36. ;         feedback        |  '------------'      |  |    | delay |
  37. ;         loop            |  .------------.      |  |    '---|---'
  38. ;                         |->| Comb Filter|------+  |        |
  39. ;                         |  |   #3       |         |      -----   reverb      
  40. ;                         |  '------------'         |       \./     gain
  41. ;                         |  .------------.         |        |
  42. ;                         |->| Comb Filter|---------+        |
  43. ;                         |  |   #4       |                  | 
  44. ;                         |  '------------'                  |
  45. ;                         |                                  V
  46. ;         .------------.  |        FIR gain          .----------.
  47. ;         |   Early    |  |         |\               |          | 
  48. ;input -->| Reflection |--+---------|  >------------>|  summer  |--- output
  49. ;      |  |    FIR     |            |/               |          |
  50. ;      |  '------------'                             '----------'      
  51. ;      |                                                  ^
  52. ;      |                                                  |
  53. ;      |                             dry gain             |
  54. ;      |                              |\                  |
  55. ;      +------------------------------|  >----------------+
  56. ;                                     |/
  57. ;    
  58. ;.............................................................................
  59. ;  COMB FILTER SUB STRUCTURE:
  60. ;                                .-------.
  61. ;      comb i        .-----.     | long  |                    comb i
  62. ;      input  ------>| sum |---->| delay |-------+--------->  output
  63. ;                    '-----'     '-------'       |
  64. ;                       ^                        |
  65. ;                       |                        V
  66. ;                       |       /|            .-----.
  67. ;                       +-----<   ------------| sum |<--------+
  68. ;                               \|            '-----'         |
  69. ;                            fdbck i             |           / \  lpf i gain
  70. ;                              gain              V         /_____\
  71. ;                                            .----------.     |
  72. ;                                            | 1 sample |     |
  73. ;                                            |   delay  |-----+
  74. ;                                            '----------'
  75. ;.............................................................................
  76. ;   UNIT (ALL PASS) REVERBERATOR STRUCTURE:
  77. ;   based on Schroeder as outlined in Griesinger: 'Practical Processors and
  78. ;   Programs for Digital Reverberation', Audio in Digital Times, 7th AES
  79. ;   conference, Toronto, Ontario, 1989
  80. ;   (the structure outlined in Moorer is a variation of this)
  81. ;
  82. ;                              -g
  83. ;                            |\
  84. ;                +---------->|  >--------------------------+
  85. ;                |           |/                            |
  86. ;                |                                         |
  87. ;                |                                         V
  88. ;    unit        |    .-----.   .--------.       |\     .-----.          unit
  89. ;    input ------+--->| sum |-->| delay  |--+--->|  >-->| sum |-----> output
  90. ;                     '-----'   '--------'  |    |/     '-----'
  91. ;                        ^                  |    1-g**2
  92. ;                        |     g            | 
  93. ;                        |       /|         |
  94. ;                        +-----<  |---------+
  95. ;                                \|
  96. ;...........................................................................
  97. ;
  98. ;    one multi-tap fir structure - to handle early reflections
  99. ;
  100. ;    followed by 4 parallel comb (iir) filters (each comb having 
  101. ;    a first order LPF in its feedback loop
  102. ;    
  103. ;    followed by an 'allpass' reverberator whose output is then 
  104. ;    delayed so that its first output follows after the last "early
  105. ;    reflection" output 
  106. ;
  107. ;__________________________________________________________________________
  108. ;
  109.     opt cex
  110.     page 132
  111.  
  112. ;--------------------------------------------------constant declarations
  113. adc    equ    $ffef        ; ADC address
  114. dac    equ    $ffef        ; DAC address
  115.  
  116. ntap    equ    7        ; number of taps    EARLY REFLECTION FIR
  117. tapmod    equ    ntap-1        ; number of taps minus 1     
  118. dlymx     equ    4000        ; length of delay line in samples
  119.  
  120. cmbdly1 equ    2205        ; COMB FILTER CONSTANTS
  121. cmbdly2 equ    2690        ; delay values (in samples)
  122. cmbdly3 equ    3175
  123. cmbdly4 equ    3440
  124.  
  125. cmbmod1 equ      3490             ; modulo for comb #1 delay line   THESE ARE
  126. cmbmod2 equ      3490         ;   "         "   #2   "   "      ALSO THE 
  127. cmbmod3    equ      3490         ;   "         "   #3  "    "      MAX DELAYS
  128. cmbmod4    equ      3490         ;   "         "   #4  "    "      ALLOWED FOR
  129.                 ;                  CHOSEN DSM
  130.                 ;                  VALUE
  131.  
  132. untrvbdly    equ    265            ; delay    UNIT (or ALLPASS)
  133. unt_g             equ    0.7            ; gains (g)    REVERBERATOR
  134. neg_g        equ    -unt_g            ;        (-g)
  135. one_m_g2    equ    (1-unt_g*unt_g)        ;    "   (1-g**2)
  136.  
  137.  
  138. cmb_g        equ    0.85        ; (OVERALL) COMB FILTER FEEDBACK GAIN 
  139.                     ; controls reverb decay time: smaller
  140.                     ; values give quicker decay, larger
  141.                     ; values yield slower decay
  142.  
  143. lpf1        equ    0.408        ; lpf filter coefficient in the 
  144. lpf2        equ    0.448        ; feedback loop of the combs,
  145. lpf3        equ    0.476        ; these LPF's simulate the high freq
  146. lpf4        equ    0.496        ; attentuation in real acoustic reverb
  147.  
  148. fdbck1        equ    cmb_g*(1-lpf1)    ; actual comb feedback gain
  149. fdbck2        equ    cmb_g*(1-lpf2)    ; is determined by the lpf filter
  150. fdbck3        equ    cmb_g*(1-lpf3)    ; coefficient and the overall feed-
  151. fdbck4        equ    cmb_g*(1-lpf4)    ; back gain to insure stability
  152.  
  153.  
  154. aligndly        equ    1305       ; alignment delay (see diagram above)
  155. alignmod        equ    1390    ;     "     mod
  156.  
  157.     
  158. reverbg        equ    0.35        ; reverberation output gain value
  159. firg        equ    0.15        ; early rflctn FIR output gain value
  160. dryg        equ    0.9999-(reverbg+firg) ; dry signal gain is rest  
  161.                     ; CHOOSE THE MIX YOU LIKE
  162.  
  163.  
  164.     org x:0
  165. chead1    dsm 3500        ; allocates 3500 data spaces for use as
  166. chead2    dsm 3500        ; comb filter tap delay lines, CHEAD1 refers
  167. chead3    dsm 3500        ; to the Comb filter HEAD (beginning) for 
  168. chead4    dsm 3500        ; filter #1  
  169.  
  170.     org x:$0f00
  171. ofst_bf    dsm    ntap        ; this reserves "ntap" contiguous addresses
  172.     org x:ofst_bf        ; starting at the closest appropriate modulo
  173. ofst0    dc    1        ; x address space.  Then starts filling the 
  174. ofst1    dc    877        ; offset buffer at this location with   
  175. ofst2    dc    1561        ; the right delay values for the 
  176. ofst3    dc    1716        ; EARLY REFLECTION FIR
  177. ofst4    dc    1826
  178. ofst5    dc    3083      ; IMPORTANT - to get no delay for the first 
  179. ofst6   dc    3510      ; early reflection, use a "1".  This is due the use
  180.               ; of an instruction code pre-decrement, a "0" value 
  181.               ; will cause a maximum delay equal to the tap delay
  182.               ; line length
  183.  
  184.  
  185.  
  186. untdly    dc    untrvbdly    ; define the UNIT REVERBERATOR delay
  187. untg1    dc    unt_g        ;    "          "              g
  188. untg2    dc    neg_g        ;    "          "         "   -g
  189. untg3    dc    one_m_g2    ;    "          "          (1-g**2)
  190. untmod    dc    untrvbdly-1    ; modulo for    "         "
  191.  
  192. algndly    dc    aligndly
  193. algnmod    dc    alignmod
  194.  
  195.     org y:$0f00
  196. gain_bf dsm ntap
  197.     org y:gain_bf        ; starting at y address zero this reserves
  198.                 ; "ntap" contiguous addresses then starts
  199.                 ; filling these addresses with the desired
  200. gain0    dc    0.213        ; tap "gain" values for EARLY REFLECTION FIR
  201. gain1    dc    0.217        ; recommended by moorer
  202. gain2    dc    0.174        ;
  203. gain3    dc    0.135        ; it is recommended to keep many early 
  204. gain4    dc    0.153        ; reflection returns, as these are fed into
  205. gain5    dc    0.157        ; comb filters, than can contribute greatly
  206. gain6    dc    0.051        ; to the later impulse response density
  207.  
  208. rvbgain    dc    reverbg        ; total reverberation gain
  209. firgain dc    firg        ; early reflection gain
  210. drygain dc    dryg        ; dry signal gain
  211.  
  212.     org y:0
  213. c1g1    dc    lpf1        ; comb #1 g1 (LPF gain)
  214. c2g1    dc    lpf2        ;      #2      
  215. c3g1    dc    lpf3        ;      #3
  216. c4g1    dc    lpf4         ;      #4
  217.  
  218.  
  219. c1g2    dc    fdbck1        ; feedback gain derived from
  220. c2g2    dc     fdbck2         ; cig2= g * (1 - cig1) where i=comb#
  221. c3g2    dc    fdbck3        
  222. c4g2    dc    fdbck4
  223.  
  224.  
  225. sample     ds 1            ; input sample storage address
  226. firout   ds 1            ; early ref FIR OUTput storage address
  227.  
  228. c1out  ds 1            ; COMB filter #1 output storage address
  229. c2out  ds 1            ;  "      "   #2   "       "       "
  230. c3out  ds 1            ;  "      "   #3   "       "       "
  231. c4out  ds 1            ;  "      "   #4   "       "       "
  232.  
  233. lpfst1    ds 1            ;  "      "   #1 Low Pass Filter state
  234. lpfst2    ds 1            ;  "      "   #2  "    "    "      "
  235. lpfst3  ds 1            ;  "      "   #3  "    "    "      "
  236. lpfst4    ds 1            ;  "      "   #4  "    "    "      "
  237.  
  238.                 ; allocates modulo memory for the unit
  239. udlyln    dsm    300        ; (allpass) reverberator delay line 
  240.  
  241. algndlyln dsm    1400        ; allocates modulo memory for alignment delay  
  242.                 ; line
  243.  
  244. dlyline    dsm dlymx        ; allocates mod memory for the FIR delay line
  245.  
  246. ;--------------------------------------------------------------------------
  247.      org     p:$40        ; program start address
  248.  
  249. ; Set up ADS board in case of force break instead of force reset
  250.        movep #0,x:$FFFE         ;set bcr to zero
  251.        movec #0,sp              ;init stack pointer
  252.        movec #0,sr              ;clear loop flag
  253.  
  254. ; Set up the SSI for operation with the DSP56ADC16EVB
  255. ; The following code sets port C to function as SCI/SSI
  256.        move #$0,a0              ;zero PCC to cycle it
  257.        movep a0,x:$FFE1
  258.        move #$0001ff,a0
  259.        movep a0,x:$FFE1         ;write PCC
  260.  
  261. ; The following code sets the SSI CRA and CRB control registers for external
  262. ; continuous clock, synchronous, normal mode.
  263.        move #$004000,a0         ;CRA pattern for word length=16 bits
  264.        movep a0,x:$FFEC
  265.        move #$003200,a0    ;CRB pattern for continous ck,sych,normal mode
  266.        movep a0,x:$FFED    ;word long frame sync: FSL=0;ext ck/fs 
  267.  
  268. ; -------------------------------------------------------------------------
  269.                 ; initialize registers MO,RO, etc
  270.     move #dlymx-1,m0    ; tap line modulus
  271.     move #dlyline,r0     ; start of delay line
  272.     move #0,n0         ; 
  273.  
  274.     move #tapmod,m1        ; tap gain line modulo
  275.     move #gain_bf,r1     ; tap gain & tap delay pointer
  276.  
  277.     move #cmbmod1,m2    ; initialize the modulo registers
  278.     move #cmbmod2,m3    ; for comb filter buffers 1 thru 5
  279.     move #cmbmod3,m4
  280.     move #cmbmod4,m5
  281.  
  282.     move #cmbdly1,n2    ; initialize the offset register
  283.     move #cmbdly2,n3    ; for Comb filters 1 thru 5
  284.     move #cmbdly3,n4
  285.     move #cmbdly4,n5
  286.  
  287.     move #chead1,r2        ; initialize the pointer values for
  288.     move #chead2,r3        ; Comb filters 1 thru 5
  289.     move #chead3,r4
  290.     move #chead4,r5
  291.  
  292.     move x:algnmod,m6    ; initialize alignment delay line
  293.     move x:algndly,n6    ; offset, modulo, and pointer registers
  294.     move #algndlyln,r6
  295.  
  296.     move x:untmod,m7    ; initialize unit reverberator (allpass)
  297.     move x:untdly,n7    ; offset, modulo, and pointer registers
  298.     move #udlyln,r7
  299.  
  300. ;---------------------------------------------------------------------------
  301. ; The following code polls the RDF flag in the SSI-SR and waits for RDF=1
  302. ; and then reads the RX register to retrieve the data from the A/D converter.
  303. ; Sample rate is controlled by DSP56ADC16 board.   
  304.  
  305. poll    jclr #7,x:$FFEE,poll     ;loop until RDF bit = 1
  306.         movep x:adc,a            ;get A/D converter data
  307. ;---------------------------------------------------------------------------
  308. ;    asr a
  309.     asr a            ; obtain data sample 
  310.                 ; and shift right for headroom
  311.     move a,y:sample        ; keep dry sample
  312.  
  313. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  314. ; FIR for early reflections
  315.     move a,y:(r0)-        ; push sample into delay line
  316.     clr a
  317.     do #ntap,fir         ; loop over the (ntaps-1),exclude fb tap now
  318.        move x:(r1),n0    ; put the tap offset value into N0
  319.        move y:(r1)+,y1    ;  "   "   "   gain   "      "  Y
  320.        move y:(r0+n0),x1    ; get delayed sample
  321.        mac x1,y1,a        ; MAC gain and sample
  322. fir      move a,y:firout        ; save FIR OUTput to y memory
  323. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  324. ; COMB 1
  325.     move y:firout,a        ; comb filter #1 with LPF in feed back
  326.     move x:(r2+n2),b    ; get delayed sample & put in b
  327.     move b,y:c1out        ; move output to y memory space
  328.  
  329.     move y:c1g1,x1        ; get LPF filter coeff
  330.     move y:lpfst1,y1    ; get LPF filter state
  331.     mac x1,y1,b        ; compute LPF output
  332.     move b,y:lpfst1        ; save LPF output to LPF state
  333.  
  334.     move y:c1g2,x1        ; get feedback coefficient
  335.     move b,y1        ; put LPF output in Y1
  336.     mac x1,y1,a        ; compute feedback term in A
  337.     move a,x:(r2)-        ; store output into delay queue
  338.  
  339. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  340. ; COMB 2
  341.     move y:firout,a        ; comb filter #1 with LPF in feed back
  342.     move x:(r3+n3),b    ; get delayed sample & put in b
  343.     move b,y:c2out        ; move output to y memory space
  344.  
  345.     move y:c2g1,x1        ; get LPF filter coeff
  346.     move y:lpfst2,y1    ; get LPF filter state
  347.     mac x1,y1,b        ; compute LPF output
  348.     move b,y:lpfst2        ; save LPF output to LPF state
  349.  
  350.     move y:c2g2,x1        ; get feedback coefficient
  351.     move b,y1        ; put LPF output in Y1
  352.     mac x1,y1,a        ; compute feedback term in A
  353.     move a,x:(r3)-        ; store output into delay queue
  354.  
  355.  
  356. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  357. ; COMB 3
  358.     move y:firout,a        ; comb filter #1 with LPF in feed back
  359.     move x:(r4+n4),b    ; get delayed sample & put in b
  360.     move b,y:c3out        ; move output to y memory space
  361.  
  362.     move y:c3g1,x1        ; get LPF filter coeff
  363.     move y:lpfst3,y1    ; get LPF filter state
  364.     mac x1,y1,b        ; compute LPF output
  365.     move b,y:lpfst3        ; save LPF output to LPF state
  366.  
  367.     move y:c3g2,x1        ; get feedback coefficient
  368.     move b,y1        ; put LPF output in Y1
  369.     mac x1,y1,a        ; compute feedback term in A
  370.     move a,x:(r4)-        ; store output into delay queue
  371. ;  -  -  -  -  -  -   -    -    -    -   -   -   -    -   -     -   - 
  372. ; COMB 4
  373.     move y:firout,a        ; 
  374.     move x:(r5+n5),b    ; get delayed sample & put in b
  375.     move b,y:c4out        ; move output to y memory space
  376.  
  377.     move y:c4g1,x1        ; get LPF filter coeff
  378.     move y:lpfst4,y1    ; get LPF filter state
  379.     mac x1,y1,b        ; compute LPF output
  380.     move b,y:lpfst4        ; save LPF output to LPF state
  381.  
  382.     move y:c4g2,x1        ; get feedback coefficient
  383.     move b,y1        ; put LPF output in Y1
  384.     mac x1,y1,a        ; compute feedback term in A
  385.     move a,x:(r5)-        ; store output into delay queue
  386. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  387.     move y:c1out,x1        ; add output of all four combs
  388.     move y:c2out,a
  389.     add x1,a
  390.     move y:c3out,x1
  391.     add x1,a
  392.     move y:c4out,x1
  393.     add x1,a
  394. ;    asr a
  395. ;  -  -  -  -  -  -  -  -  -   -   -      -   -    -   -  -  -    -  
  396. ;                 all pass unit reverberator                
  397.     clr b
  398.     move a,x1
  399.     move x:untg2,y1
  400.     mac x1,y1,b
  401.  
  402.     move y:(r7+n7),x1    ; get delayed sample
  403.     move x:untg3,y1        ; get gain (1-g**2)
  404.     mac x1,y1,b        ; MAC into b for output (B CONTAINS OUTPUT)
  405.  
  406.     move x:untg1,y1        ; get gain g
  407.     mac x1,y1,a
  408.     move a,y:(r7)-        ; put new+g*delayed into delay line/inc r7
  409.     move b,y:(r6)-        ;store the output in a queue for align delay
  410. ;  -    -     -     -     -     -     -     -     -     -     -      -     -
  411.     move y:(r6+n6),y1    ; get the delayed unit rvb sample
  412.     move y:rvbgain,x1    ; and the reverb gain
  413.     mpy x1,y1,a
  414.  
  415.     move y:firout,y1    ; get the early reflection FIR output sample
  416.     move y:firgain,x1    ; and FIR gain
  417.     mac x1,y1,a
  418.  
  419.     move y:sample,y1    ; mix in the dry sample
  420.     move y:drygain,x1    ; by the dry gain
  421.     mac x1,y1,a        ; A now contains the output sample
  422.     asr a
  423. ;  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
  424. ; Write DSP56ADC16 A/D converter data to the PCM-56
  425.  
  426.            move a,x:dac          ;write the PCM-56 D/A via SSI xmt reg.
  427.            jmp poll                ;loop indefinitely
  428.  
  429.            end
  430. ə     
  431. ə